#include "EnvironmentFactory.h"

EnvironmentFactory::EnvironmentFactory() 
{
}

Environment* EnvironmentFactory::generateEnvironment() 
{
    //TODO: In the future, we should
    //look at ways of dynamically discovering which environments are available on
    //the system, and loading them up.  Also, we should look at dynamically querying
    //an environment about what options / solutions / whatever it supports.
    
    cout << "Which of the following environments do you wish to use?" << endl;
    cout << SALESMAN_ENVIRONMENT << ") Traveling Salesman Environment" << endl;
    cout << KNAPSACK_ENVIRONMENT << ") Knapsack Environment" << endl;
    cout << MINESWEEPER_ENVIRONMENT << ") MineSweeper Environment" << endl;
    cout << JOB_SHOP_SCHEDULING_ENVIRONMENT << ") Job Shop Scheduling Environment" << endl;
    int answer;
        
    while (true) 
    {
        cout << "? ";
        cin >> answer;
        
        try
        {
            return generateEnvironment(answer);
        }
        catch (std::exception &e)
        {
            cout << "Invalid selection." << endl;
        }
    }
}

Environment* EnvironmentFactory::generateEnvironment(int environmentType) 
{
    switch (environmentType)
    {
        case SALESMAN_ENVIRONMENT:
        {
            return TravelingSalesmanEnvironment<>::getEnvironment();
            break;
        }
        case KNAPSACK_ENVIRONMENT:
        {
            return KnapsackEnvironment<>::getEnvironment();
            break;
        }
        case MINESWEEPER_ENVIRONMENT:
        {
            return MineSweeperEnvironment::getEnvironment();
            break;
        }
        case JOB_SHOP_SCHEDULING_ENVIRONMENT:
        {
            return JobShopSchedulingEnvironment<>::getEnvironment();
            break;
        }
        default:
        {
            throw Unsupported_environment_exception();
            break;
        }
    }
}

vector<string> EnvironmentFactory::getEnvironmentNames()
{
    vector<string> names;
    names.push_back(TravelingSalesmanEnvironment<>::getName());
    names.push_back(KnapsackEnvironment<>::getName());
    names.push_back(MineSweeperEnvironment::getName());
    names.push_back(JobShopSchedulingEnvironment<>::getName());
    return names;
}
